package com.geo.geotool.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.geo.geotool.entity.geo.GeoFileInfo;
import com.geo.geotool.service.IShpService;
import com.geo.geotool.service.geofile.fileCharset.GeoFileCharsetCaptureFactory;
import com.geo.geotool.service.geofile.fileCharset.IFileCharsetCapture;
import lombok.extern.slf4j.Slf4j;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.referencing.CRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.filter.Filter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.springframework.stereotype.Service;
import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * • @Description: shape文件解析类
 * • @author  : yell
 * • @date : 2021/11/24  12:24
 */
@Service
@Slf4j
public class ShpServiceImpl implements IShpService {

    @Override
    public GeoFileInfo parseShp(File file, Filter filter) throws Exception {
        return readShp(file,filter);
    }

    /**读取shp文件*/
    public GeoFileInfo readShp(File file, Filter filter) throws Exception{
        GeoFileInfo geoFileInfo = new GeoFileInfo();
        JSONArray geoArray = new JSONArray();
        /**查看当前编码格式*/
        IFileCharsetCapture fileCharsetCapture =
                GeoFileCharsetCaptureFactory.getFileCharsetCapture(file.getPath());
        String charsetName = fileCharsetCapture.getCharsetName(file.getPath());
        /**读取shapeFile*/
        ShapefileDataStore shapefileDataStore = new ShapefileDataStore(file.toURL());
        shapefileDataStore.setCharset(Charset.forName(charsetName));
        SimpleFeatureSource simpleFeatureSource = shapefileDataStore.getFeatureSource();
        if(null == simpleFeatureSource){
            return null;
        }
        /**设置图层名称**/
        geoFileInfo.setLayerName(simpleFeatureSource.getName().toString());
        /**读取坐标系*/
        CoordinateReferenceSystem referenceSystem = simpleFeatureSource.getSchema().getCoordinateReferenceSystem();
        int srId = CRS.lookupEpsgCode(referenceSystem,true);
        geoFileInfo.setSrId(srId+"");

        /**获取其他元数据信息**/
        List<Map> attributeList = new ArrayList<>();
        List<AttributeDescriptor>  attributeDescriptorList = simpleFeatureSource.getSchema().getAttributeDescriptors();
        for(AttributeDescriptor attributeDescriptor : attributeDescriptorList){
            Map<String,String> attributeMap = new HashMap<>();
            attributeMap.put("name",attributeDescriptor.getName().toString());
            Class<?> type = attributeDescriptor.getType().getBinding();
            attributeMap.put("type",type.getName());
            attributeList.add(attributeMap);
        }
        geoFileInfo.setAttributeList(attributeList);
        /**获取地理信息**/
        SimpleFeatureCollection simpleFeatureCollection =
                (filter==null?simpleFeatureSource.getFeatures():simpleFeatureSource.getFeatures(filter));
        SimpleFeatureIterator featureIterator = simpleFeatureCollection.features();
        while(featureIterator.hasNext()){
            SimpleFeature feature = featureIterator.next();
            String featureSrId = String.valueOf(srId);
            FeatureJSON featureJSON = new FeatureJSON();
            /**设置是否写CRS坐标信息*/
            featureJSON.setEncodeFeatureCRS(true);
            JSONObject jsonObject = JSONObject.parseObject(featureJSON.toString(feature));
            JSONObject geometry = jsonObject.getJSONObject("geometry");
            if(!geometry.containsKey("crs")){
                geometry.put("crs","EPSG:"+featureSrId);
            }
            geoArray.add(jsonObject);
        }
        geoFileInfo.setGeoJson(geoArray);
        return geoFileInfo;
    }
}
